package io.kiki.stack.http.feign.metrics5;

import feign.Request.Options;
import io.dropwizard.metrics5.MetricRegistry;
import io.dropwizard.metrics5.Timer;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;

/**
 * Warp feign {@link AsyncClient} with metrics.
 */
public class MeteredAsyncClient extends BaseMeteredClient implements AsyncClient<Object> {

    private final AsyncClient<Object> asyncClient;

    public MeteredAsyncClient(AsyncClient<Object> asyncClient, MetricRegistry metricRegistry, MetricSuppliers metricSuppliers) {
        super(metricRegistry, new FeignMetricName(AsyncClient.class), metricSuppliers);
        this.asyncClient = asyncClient;
    }

    @Override
    public CompletableFuture<Response> execute(Request request, Options options, Optional<Object> requestContext) {
        final RequestTemplate template = request.requestTemplate();
        final Timer.Context timer = createTimer(template);
        return asyncClient.execute(request, options, requestContext).whenComplete((response, th) -> {
            if (th == null) {
                recordSuccess(template, response);
            } else
                if (th instanceof FeignException) {
                    FeignException e = (FeignException) th;
                    recordFailure(template, e);
                } else
                    if (th instanceof Exception) {
                        Exception e = (Exception) th;
                        recordFailure(template, e);
                    }
        }).whenComplete((response, th) -> timer.close());
    }
}
